namespace mecs {

    /** 
     * 构造函数中的数据是浅拷贝
     * 创建必须使用world中的CompCreater
     * 在定义时不能初始化数值
     * 继承此类的名字，即是此组件的 compName
     * 默认使用 static NAME 防止重名comp类
     * 如果使用了列表的变量，则列表中必须是基本数据结构，否则需要自行覆盖cloneData/resetData来缓存
     */
    export abstract class BaseComp implements IDataNode {


        constructor(data?: any) {
            // this.setCompName()
            this.mLowCpData(data);
        }

        get compName() {
            return this["constructor"]["NAME"]
        }

        protected mLowCpData(data: any) {
            if (!data) return;
            for (var key in data) {
                var element = data[key];
                if (Array.isArray(element)) {
                    this[key] = element.slice(0);
                } else {
                    this[key] = element
                }
            }
        }

        /** 默认根据类型清空，如果需要特殊的数据清空，自行重写此方法 */
        clear() {
            for (let key in this) {
                let element = this[key];
                let type = typeof element;
                if (type == "string") {
                    Object.defineProperty(this, key, { value: '' })
                } else if (type == "number") {
                    Object.defineProperty(this, key, { value: 0 })
                } else if (type == "boolean") {
                    Object.defineProperty(this, key, { value: false })
                } else if (type == "object") {
                    Object.defineProperty(this, key, { value: null })
                }
            }
        }

        /** 将当前的需要变化的数据克隆一份，如果变量是数组且其中是object结构的数组，需要自行覆盖 */
        cloneData(): any {
            return this.mLowCacheData();
        }

        protected mLowCacheData() {
            let d: any = {};
            for (let key in this) {
                let element = this[key];
                let type = typeof element
                if (type == "string" || type == "number" || type == "boolean" || type == "undefined" || element === null) {
                    d[key] = element;
                } else if (Array.isArray(element)) {
                    d[key] = element.slice(0);
                }
            }
            return d;
        }

        /** 将clone的数据重新赋值回来 */
        resetData(data: any) {
            if (!data) return;
            if (typeof data == 'string') {
                data = JSON.parse(data);
            }
            this.mLowCpData(data);
        }

        dispose() { }
    }
}